package main

import (
	"encoding/json"
	"fmt"
	"github.com/fatih/color"
	"github.com/sirupsen/logrus"
	"golang.org/x/crypto/ssh/terminal"
	"path/filepath"
	"strings"
	"time"
)

type JavaFormatter struct {
	EnablePackageAbbrev bool
	EnableColor         bool // 控制颜色开关
	isTerminal          bool // 自动检测是否终端
}

// 颜色定义
var (
	levelColors = map[logrus.Level]string{
		logrus.DebugLevel: color.New(color.FgCyan).SprintFunc()("%s"),
		logrus.InfoLevel:  color.New(color.FgGreen).SprintFunc()("%s"),
		logrus.WarnLevel:  color.New(color.FgYellow).SprintFunc()("%s"),
		logrus.ErrorLevel: color.New(color.FgRed).SprintFunc()("%s"),
		logrus.FatalLevel: color.New(color.FgMagenta).SprintFunc()("%s"),
		logrus.PanicLevel: color.New(color.FgHiRed).SprintFunc()("%s"),
	}
	resetColor = "\033[0m"
)

func (f *JavaFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	timestamp := time.Now().Format("2006-01-02 15:04:05.000")

	// 处理日志级别颜色
	levelText := strings.ToUpper(entry.Level.String())
	if f.EnableColor && f.isTerminal {
		if colorFunc, ok := levelColors[entry.Level]; ok {
			levelText = fmt.Sprintf(colorFunc, fmt.Sprintf("%-7s", levelText))
		}
	} else {
		levelText = fmt.Sprintf("%-7s", levelText)
	}

	// 处理调用者信息
	var callerInfo string
	if entry.HasCaller() {
		fileName := filepath.Base(entry.Caller.File)

		var pkgAbbrev string
		if f.EnablePackageAbbrev {
			fnParts := strings.Split(entry.Caller.Function, "/")
			for _, part := range fnParts[:len(fnParts)-1] {
				if dotIdx := strings.Index(part, "."); dotIdx > 0 {
					pkgAbbrev += part[:dotIdx] + "."
				} else if len(part) > 0 {
					pkgAbbrev += string(part[0]) + "."
				}
			}
			pkgAbbrev = strings.TrimSuffix(pkgAbbrev, ".")
		}
		callerInfo = fmt.Sprintf("[%s:%d] [%s]", fileName, entry.Caller.Line, pkgAbbrev)
	}

	// 处理附加字段
	var fieldsStr string
	if len(entry.Data) > 0 {
		fields, _ := json.Marshal(entry.Data)
		fieldsStr = " " + string(fields)
	}
	var msg string
	// 构建完整消息
	if f.EnableColor {
		msg = fmt.Sprintf("%s %s %s - %s%s%s\n",
			timestamp,
			levelText,
			callerInfo,
			entry.Message,
			fieldsStr,
			resetColor,
		)
	} else {
		msg = fmt.Sprintf("%s %s %s - %s%s\n",
			timestamp,
			levelText,
			callerInfo,
			entry.Message,
			fieldsStr,
		)
	}

	return []byte(msg), nil
}

// 终端检测（需导入golang.org/x/crypto/ssh/terminal）
func isTerminalCheck(fd uintptr) bool {
	return terminal.IsTerminal(int(fd))
}
